package com.haohope.framework.wb.online;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import javax.servlet.http.HttpSession;

import org.springframework.session.data.redis.RedisIndexedSessionRepository;

import com.wb.common.Var;
import com.wb.util.StringUtil;

public class RedisOnlineServiceImpl implements OnlineService{
	private final String SPRINGSESSIONKEY = "spring:session:sessions";
	private final String SPRINGSESSIONEXPIRESKEY = "expires";
	private final String SPRINGSESSIONATTR = "sessionAttr";
	private RedisIndexedSessionRepository redisTemplate;
	public RedisOnlineServiceImpl(RedisIndexedSessionRepository redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
	private Map<String,List<Map<Object,Object>>> getUsers(){
		Set<Object> keys = redisTemplate.getSessionRedisOperations().keys(SPRINGSESSIONKEY+":*");
		keys = keys.parallelStream().filter(i->!i.toString().toLowerCase().contains(SPRINGSESSIONEXPIRESKEY)).collect(Collectors.toSet());
		List<Map<Object,Object>> onlineusers = new ArrayList<Map<Object,Object>>();
		for(Object key:keys) {
			Map<Object, Object> map = redisTemplate.getSessionRedisOperations().opsForHash().entries(key);
			map.put("sessionid", key);
			onlineusers.add(map);
		}
		
		onlineusers = onlineusers.parallelStream()
				                 .filter(i->i.containsKey(SPRINGSESSIONATTR+":"+OnlineService.SIMPLELISTENER))
				                 .collect(Collectors.toList());
		//分组
		return onlineusers.parallelStream().collect(Collectors.groupingBy(i->(String)i.get(SPRINGSESSIONATTR+":"+OnlineService.USER)));
		
	}
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public OnlineUserGridResult doGetUserList(int start, int limit) {
		Map<String,List<Map<Object,Object>>> users = getUsers();
		int index = -1;
		List<OnlineUserVo> rows = new ArrayList<OnlineUserVo>();
		Set<Entry<String, List<Map<Object,Object>>>> es = users.entrySet();
		if (limit > Var.limitRecords) {
			limit = Var.limitRecords;
		}

		int end = start + limit;
		Iterator var14 = es.iterator();

		while (var14.hasNext()) {
			Entry<String, List<Map<String,Object>>> e = (Entry) var14.next();
			++index;
			if (index >= start) {
				if (index >= end) {
					break;
				}

				List<Map<String,Object>> sessions = (List<Map<String,Object>>) e.getValue();
				int sessionCount = 0;
				Map<String,Object> session = null;

				for (Iterator var16 = sessions.iterator(); var16.hasNext(); ++sessionCount) {
					Map<String,Object> sess = (Map<String,Object>) var16.next();
					if (session == null) {
						session = sess;
					}
				}

				if (sessionCount != 0) {
					OnlineUserVo row = new OnlineUserVo();
					row.setSessionCount(sessionCount);
					row.setUser(e.getKey());

					try {
						row.setUsername((String)session.get(SPRINGSESSIONATTR+":"+OnlineService.USERNAME));
						row.setDispname((String)session.get(SPRINGSESSIONATTR+":"+OnlineService.DISPNAME));
						row.setIp((String)session.get(SPRINGSESSIONATTR+":"+OnlineService.IP));
						row.setUserAgent((String)session.get(SPRINGSESSIONATTR+":"+OnlineService.USERAGENT));
						rows.add(row);
					} catch (Throwable var17) {
						--index;
					}
				}
			}
		}
		return new OnlineUserGridResult(users.size(),rows);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public OnlineSessionGridResult doGetSessionList(String user, int start, int limit) {
		Map<String,List<Map<Object,Object>>> users = getUsers();
		int index = -1;
		List<OnlineSessionVo> rows = new ArrayList<OnlineSessionVo>();
		List<Map<Object,Object>> sessions = (List<Map<Object,Object>>) users.get(user);
		if (limit > Var.limitRecords) {
			limit = Var.limitRecords;
		}

		int end = start + limit;
		if (sessions != null) {
			Iterator var12 = sessions.iterator();

			while (var12.hasNext()) {
				Map<String,Object> session = (Map<String,Object>) var12.next();
				++index;
				if (index >= start) {
					if (index >= end) {
						break;
					}

					OnlineSessionVo row = new OnlineSessionVo();

					try {
						row.setIp((String)session.get(SPRINGSESSIONATTR+":"+OnlineService.IP));
						row.setUserAgent((String)session.get(SPRINGSESSIONATTR+":"+OnlineService.USERAGENT));
						row.setCreateDate(new Date(Long.valueOf(session.get("creationTime").toString())));
						row.setLastAccessDate(new Date(Long.valueOf(session.get("lastAccessedTime").toString())));
						rows.add(row);
					} catch (Throwable var14) {
						var14.printStackTrace();
						--index;
					}
				}
			}
		}
		return new OnlineSessionGridResult(sessions == null ? 0l : sessions.size(),rows);
	}
	public void doAdd(String userId, HttpSession session) {
		/*
		boolean uniqueLogin = Var.getBool("sys.session.uniqueLogin");
		if(uniqueLogin) {
			Map<String,List<Map<Object,Object>>> users = getUsers();
			if(null != users && users.size() > 0 && null!=users.get(userId) && users.get(userId).size() > 0) {
				List<Map<Object,Object>> sessions = users.get(userId);
				Set<String> sessionids = sessions.stream().map(i->i.get("sessionid").toString()).collect(Collectors.toSet());
				Set<String> _sessionids = sessionids.stream().map(i->i.replace(SPRINGSESSIONKEY, SPRINGSESSIONKEY+":"+SPRINGSESSIONEXPIRESKEY)).collect(Collectors.toSet());
				redisTemplate.getSessionRedisOperations().delete(sessionids);
				redisTemplate.getSessionRedisOperations().delete(_sessionids);
			}
		}
		*/
	}
	public void doRemove(String userId, HttpSession session) {
		String sessionid = session.getId();
		redisTemplate.getSessionRedisOperations().delete(SPRINGSESSIONKEY+":"+sessionid);
		redisTemplate.getSessionRedisOperations().delete(SPRINGSESSIONKEY+":"+SPRINGSESSIONEXPIRESKEY+":"+sessionid);
	}
	public void doInvalidate(String[] userIds) {
		Map<String,List<Map<Object,Object>>> users = getUsers();
		for(String userid:userIds) {
			List<Map<Object,Object>> sessions = users.get(userid);
			if(null!=sessions && sessions.size()>0) {
				for(Map<Object,Object> session:sessions) {
					String sessionid = (String) session.get("sessionid");
					sessionid = sessionid.replace(SPRINGSESSIONKEY+":", "");
					redisTemplate.getSessionRedisOperations().delete(SPRINGSESSIONKEY+":"+sessionid);
					redisTemplate.getSessionRedisOperations().delete(SPRINGSESSIONKEY+":"+SPRINGSESSIONEXPIRESKEY+":"+sessionid);
				}
			}
		}
		
	}
	@SuppressWarnings("rawtypes")
	public void doUpdate(String userId, String[] roles, boolean status) {
		Map<String,List<Map<Object,Object>>> users = getUsers();
		List<Map<Object,Object>> sessions = (List<Map<Object,Object>>) users.get(userId);
		if (sessions != null) {
			if (status) {
				Iterator var5 = sessions.iterator();

				while (var5.hasNext()) {
					@SuppressWarnings("unchecked")
					Map<String,Object> session = (Map<String,Object>) var5.next();

					try {
						redisTemplate.getSessionRedisOperations().opsForHash().put(session.get("sessionid"), SPRINGSESSIONATTR+":sys.roles", roles);
						redisTemplate.getSessionRedisOperations().opsForHash().put(session.get("sessionid"), SPRINGSESSIONATTR+":sys.roleList", StringUtil.join(roles, ","));
						//session.setAttribute("sys.roleList", StringUtil.join(roles, ","));
					} catch (Throwable var7) {
						;
					}
				}
			} else {
				//String[] userIds = new String[]{userId};
				//invalidate(userIds);
				if(null!=sessions && sessions.size()>0) {
					for(Map<Object,Object> session:sessions) {
						String sessionid = (String) session.get("sessionid");
						sessionid = sessionid.replace(SPRINGSESSIONKEY+":", "");
						redisTemplate.getSessionRedisOperations().delete(SPRINGSESSIONKEY+":"+sessionid);
						redisTemplate.getSessionRedisOperations().delete(SPRINGSESSIONKEY+":"+SPRINGSESSIONEXPIRESKEY+":"+sessionid);
					}
				}
			}
		}
	}

}
